package org.yinxue.example.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * SimpleNettyServer {@link org.yinxue.example.netty.server} <br>
 *
 * @author zengjian
 * @date 2019/7/9 20:25
 * @since 1.0.0
 */
public class SimpleNettyServer {

    private String host;
    private Integer port;
    private List<ChannelHandler> channelHandlerList;
    ServerBootstrap bootstrap = new ServerBootstrap();

    public SimpleNettyServer(String host, Integer port) {
        this.host = host;
        this.port = port;
        this.channelHandlerList = new ArrayList<>();
    }

    public SimpleNettyServer addChannelHandler(ChannelHandler handler) {
        channelHandlerList.add(handler);
        return this;
    }

    public void start() throws InterruptedException {
        bootstrap = new ServerBootstrap()
                .channel(NioServerSocketChannel.class)
                .group(new NioEventLoopGroup(), new NioEventLoopGroup())
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
//                        channelHandlerList.stream().forEach(channelHandler -> socketChannel.pipeline().addLast(channelHandler));
                        socketChannel.pipeline().addLast(new HttpServerCodec());
//                        socketChannel.pipeline().addLast(new HttpServerCodec()).addLast(new SimpleChannelInboundHandler<HttpRequest>() {
//                            @Override
//                            protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpRequest httpRequest) throws Exception {
//                                System.out.println(httpRequest.uri());
//                                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
//                                response.content().writeBytes("hello".getBytes());
//                                channelHandlerContext.writeAndFlush(response);
//                            }
//                        });
                        // 不论是哪种协议的数据进入设计的端口都可以接收到，主要在于业务转换
                        socketChannel.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpRequest object) throws Exception {
//                                while (byteBuf.isReadable()) {
//                                    System.out.println("读取：" + byteBuf.readByte());
//                                }
                                System.out.println("hello");
                                channelHandlerContext.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK));
                            }
                        });
//                        socketChannel.pipeline().addLast(new SimpleChannelInboundHandler<HttpObject>() {
//                            @Override
//                            protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
//                                if (msg instanceof HttpRequest) {
//                                    HttpRequest request = (HttpRequest) msg;
//                                    System.out.println("接收到Http请求:\n" + request.toString());
//                                    FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
//                                    ChannelFuture future1 = ctx.writeAndFlush(fullHttpResponse);
//                                    future1.addListener(new ChannelFutureListener() {
//                                        @Override
//                                        public void operationComplete(ChannelFuture future) throws Exception {
//                                            if (future.isSuccess()) {
//                                                System.out.println("返回消息OK");
//                                            } else {
//                                                System.out.println("返回消息失败");
//                                            }
//                                        }
//                                    });
//                                }
//                            }
//
//                            @Override
//                            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//                                cause.printStackTrace();
//                                ctx.channel().close();
//                            }
//                        });
                    }
                });
//                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.FALSE)
        // SO_BACKLOG只能用于option设置，不能再childOption中
//                .option(ChannelOption.SO_BACKLOG, 1000);
        ChannelFuture future = bootstrap.bind("localhost", port).sync();
        future.channel().closeFuture().syncUninterruptibly();
    }

    public static void main(String[] args) throws IOException, InterruptedException {
//        new Thread(() -> new SimpleNettyServer("localhost", 8090).addChannelHandler(new ChannelInboundHandlerAdapter() {
        ////            @Override
        ////            public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ////                System.out.println(ctx.channel().localAddress());
        ////            }
        ////
        ////            @Override
        ////            public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        ////                System.out.println("注册");
        ////            }
        ////        }).start()).start();
        //
        //        //
        new SimpleNettyServer("127.0.0.1", 9090)
                .start();
    }
}